package com.drerp.RH.DAO;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.drerp.util.HibernateUtil;

public abstract class GenericoDAO<T, ID extends Serializable> {
	protected Session getSession() {
		return HibernateUtil.getSessionFactory().getCurrentSession();
	}
	
	public void save(T entity) {
		Transaction trans = null;
		Session hibernateSession = this.getSession();
		
		try {
			trans = hibernateSession.beginTransaction();
			
			hibernateSession.saveOrUpdate(entity);
			
			trans.commit();
		} catch (RuntimeException e) {
			if (trans != null) {
				trans.rollback();
			}
			
			e.printStackTrace();
		}
	}
	
	public void delete(T entity) {
		Transaction trans = null;
		Session hibernateSession = this.getSession();
		
		try {
			trans = hibernateSession.beginTransaction();
			
			hibernateSession.delete(entity);
			
			trans.commit();
		} catch (RuntimeException e) {
			if (trans != null) {
				trans.rollback();
			}
			
			e.printStackTrace();
		}
	}

	/***
	 * Executa uma Query e retorna uma lista.<br>
	 * Lembrar de <b>criar uma Transaction</b> antes de chamar esse método.
	 */
	public List<T> findMany(Query query) {
		List<T> t = null;
		t = (List<T>) query.list();
		return t;
	}

	/***
	 * Executa uma Query e retorna um único resultado.<br>
	 * Lembrar de <b>criar uma Transaction</b> antes de chamar esse método.
	 */
	public T findOne(Query query) {
		T t = null;
		t = (T) query.uniqueResult();
		return t;
	}

	public List<T> findAll(Class<T> clazz) {
		List<T> list = null;
		
		Transaction trans = null;
		Session hibernateSession = this.getSession();
		
		try {
			trans = hibernateSession.beginTransaction();
			
			Query query = hibernateSession.createQuery("from " + clazz.getName());
			list = query.list();
			
			trans.commit();
		} catch (RuntimeException e) {
			if (trans != null) {
				trans.rollback();
			}
			
			e.printStackTrace();
		}
		
		return list;
	}

	public T findById(Class<T> clazz, ID id) {
		T t = null;
		
		Transaction trans = null;
		Session hibernateSession = this.getSession();
		
		try {
			trans = hibernateSession.beginTransaction();
			
			t = (T) hibernateSession.get(clazz, id);
			
			trans.commit();
		} catch (RuntimeException e) {
			if (trans != null) {
				trans.rollback();
			}
			
			e.printStackTrace();
		}
		
		return t;
	}
	
	public long count(Class<T> clazz) {
		long count = 0;
		
		Transaction trans = null;
		Session hibernateSession = this.getSession();
		
		try {
			trans = hibernateSession.beginTransaction();
			
			String hql = "select count(*) from " + clazz.getName();
			Query query = hibernateSession.createQuery(hql);
			count = (Long) query.uniqueResult();
			
			trans.commit();
		} catch (RuntimeException e) {
			if (trans != null) {
				trans.rollback();
			}
			
			e.printStackTrace();
		}
		
		return count;
	}

}
